import fs from 'fs/promises';
import path from 'path';
import { ParserOptions, ParseResult, ResourceConfig } from '../types';
import { logger } from '../../utils/logger';

export class ResourceParser {
  private options: ParserOptions;

  constructor(options: ParserOptions) {
    this.options = options;
  }

  /**
   * 解析资源文件
   * @param config 资源配置
   */
  public async parseResource(config: ResourceConfig): Promise<ParseResult | null> {
    try {
      logger.info('开始解析资源文件', { path: config.path });

      // 检查文件是否存在
      try {
        await fs.access(config.path);
      } catch (error) {
        logger.warn('资源文件不存在', { path: config.path });
        return null;
      }

      // 读取文件内容
      const content = await fs.readFile(config.path, {
        encoding: config.encoding || 'utf8' as BufferEncoding
      });

      // 根据文件格式选择解析器
      const format = config.format || this.detectFormat(config.path);
      const parser = this.getParser(format);

      if (!parser) {
        logger.warn('不支持的资源文件格式', { 
          path: config.path, 
          format 
        });
        return null;
      }

      // 解析文件内容
      const result = await parser(content, config);
      
      logger.info('资源文件解析成功', { 
        path: config.path, 
        translationCount: result.translations.size 
      });

      return result;
    } catch (error) {
      logger.error('资源文件解析失败', { 
        path: config.path, 
        error: error instanceof Error ? error.message : String(error) 
      });
      return null;
    }
  }

  /**
   * 检测文件格式
   */
  private detectFormat(filePath: string): string {
    const ext = path.extname(filePath).toLowerCase();
    switch (ext) {
      case '.xml':
        return 'xml';
      case '.json':
        return 'json';
      case '.properties':
        return 'properties';
      case '.strings':
        return 'strings';
      default:
        return '';
    }
  }

  /**
   * 获取对应的解析器
   */
  private getParser(format: string): ((content: string, config: ResourceConfig) => Promise<ParseResult>) | null {
    switch (format) {
      case 'xml':
        return this.parseXML;
      case 'json':
        return this.parseJSON;
      case 'properties':
        return this.parseProperties;
      case 'strings':
        return this.parseStrings;
      default:
        return null;
    }
  }

  /**
   * XML文件解析器
   */
  private async parseXML(content: string, config: ResourceConfig): Promise<ParseResult> {
    // TODO: 实现XML解析
    throw new Error('XML解析器未实现');
  }

  /**
   * JSON文件解析器
   */
  private async parseJSON(content: string, config: ResourceConfig): Promise<ParseResult> {
    const data = JSON.parse(content);
    const translations = new Map<string, string>();

    // 处理嵌套的JSON结构
    const flattenObject = (obj: any, prefix = '') => {
      Object.entries(obj).forEach(([key, value]) => {
        const newKey = prefix ? `${prefix}.${key}` : key;
        if (typeof value === 'object' && value !== null) {
          flattenObject(value, newKey);
        } else {
          translations.set(newKey, String(value));
        }
      });
    };

    flattenObject(data);

    return {
      language: this.detectLanguage(config.path),
      translations
    };
  }

  /**
   * Properties文件解析器
   */
  private async parseProperties(content: string, config: ResourceConfig): Promise<ParseResult> {
    const translations = new Map<string, string>();
    const lines = content.split('\n');

    lines.forEach(line => {
      line = line.trim();
      if (line && !line.startsWith('#')) {
        const [key, ...valueParts] = line.split('=');
        const value = valueParts.join('=').trim();
        if (key && value) {
          translations.set(key.trim(), value);
        }
      }
    });

    return {
      language: this.detectLanguage(config.path),
      translations
    };
  }

  /**
   * Strings文件解析器
   */
  private async parseStrings(content: string, config: ResourceConfig): Promise<ParseResult> {
    const translations = new Map<string, string>();
    const lines = content.split('\n');

    lines.forEach(line => {
      line = line.trim();
      if (line && !line.startsWith('//')) {
        const match = line.match(/"([^"]+)"\s*=\s*"([^"]+)";/);
        if (match) {
          const [, key, value] = match;
          translations.set(key, value);
        }
      }
    });

    return {
      language: this.detectLanguage(config.path),
      translations
    };
  }

  /**
   * 从文件路径检测语言
   */
  private detectLanguage(filePath: string): string {
    const match = filePath.match(/([a-z]{2}(?:-[A-Z]{2})?)\.[^.]+$/);
    return match ? match[1] : 'en';
  }
} 